import {ErrorCode, NatsError} from "nats.ws"

class Error_resolver {

    authError;
    authTimeout;
    permissionError;
    protocolError;
    jetStreamError;
    jsError;
    otherError;

    constructor() {
        this.authError = new Map();
        this.authTimeout = new Map();
        this.permissionError = new Map();
        this.protocolError = new Map();
        this.jetStreamError = new Map();
        this.jsError = new Map();
        this.otherError = new Map();
        this.initErrorCode();
    }

    initErrorCode() {

        this.authError.set(ErrorCode.AuthorizationViolation, null);
        this.authError.set(ErrorCode.AuthenticationExpired, null);

        this.authTimeout.set(ErrorCode.AuthenticationTimeout, "AUTHENTICATION_TIMEOUT");

        this.permissionError.set(ErrorCode.PermissionsViolation, null);

        this.protocolError.set(ErrorCode.ProtocolError, "NATS_PROTOCOL_ERR")

        this.jetStreamError.set(ErrorCode.JetStreamInvalidAck, ErrorCode.JetStreamInvalidAck);
        this.jetStreamError.set(ErrorCode.JetStream404NoMessages, "JetStream404NoMessages");
        this.jetStreamError.set(ErrorCode.JetStream408RequestTimeout, "JetStream408RequestTimeout");
        this.jetStreamError.set(ErrorCode.JetStream409MaxAckPendingExceeded, "JetStream409MaxAckPendingExceeded");
        this.jetStreamError.set(ErrorCode.JetStreamNotEnabled, "JetStreamNotEnabled");
        this.jetStreamError.set(ErrorCode.JetStreamIdleHeartBeat, ErrorCode.JetStreamIdleHeartBeat);

        this.jsError.set(ErrorCode.ApiError, ErrorCode.ApiError);

        this.otherError.set(ErrorCode.Timeout, ErrorCode.Timeout);
        this.otherError.set(ErrorCode.Unknown, ErrorCode.Unknown);
        this.otherError.set(ErrorCode.NoResponders, "NoResponders")
        this.otherError.set(ErrorCode.MaxPayloadExceeded, ErrorCode.MaxPayloadExceeded)
        this.otherError.set(ErrorCode.SubClosed , ErrorCode.SubClosed);
        this.otherError.set(ErrorCode.SubDraining , ErrorCode.SubDraining);
        this.otherError.set(ErrorCode.ConnectionClosed , ErrorCode.ConnectionClosed);
        this.otherError.set(ErrorCode.ConnectionDraining , ErrorCode.ConnectionDraining);
        this.otherError.set(ErrorCode.ConnectionRefused , ErrorCode.ConnectionRefused);
        this.otherError.set(ErrorCode.ConnectionTimeout , ErrorCode.ConnectionTimeout);
        this.otherError.set(ErrorCode.Disconnect , ErrorCode.Disconnect);
    }


    resolver(err) {
        if (err instanceof NatsError) {
            if (err.isAuthError()) {
                let error = this.authError.get(err.code);
                return error ? error : err.message;
            } else if (err.isAuthTimeout()) {
                let error = this.authTimeout.get(err.code);
                return error ? error : err.message;
            } else if (err.isPermissionError()) {
                let error = this.permissionError.get(err.code);
                return error ? error : err.message;
            } else if (err.isProtocolError()) {
                let error = this.protocolError.get(err.code);
                return error ? error : err.message;
            } else if (err.isJetStreamError()) {
                let error = this.jetStreamError.get(err.code);
                return error ? error : err.message;
            } else if (err.jsError()) {
                return err.api_error.description;
            } else if (this.otherError.has(err.code)) {
                return this.otherError.get(err.code);
            } else {
                console.error(JSON.stringify(err));
                return "UnKnown Error";
            }
        } else {
            return "UnKnown Error";
        }
    }
}


export default Error_resolver;